-module(erlol).
%-compile([native]).
-export([
    run_string/1,
    run_string_debug/1,
    run_file/1,
    run_file/2,
    test/0
    ]).

read_file(Read, Dev) when is_list(Read) ->
    case io:get_chars(Dev, undefined, 1024) of
        eof -> Read;
        NewString when is_list(NewString) -> read_file(Read++NewString, Dev)
    end.

file_get_contents(Name) ->
    {ok, Dev} = file:open(Name, [read, read_ahead]),
    String = read_file([], Dev),
    file:close(Dev),
    String.
    

run_file(Name) -> run_file(Name, false).
run_file(Name, Debug) ->
    Contents = file_get_contents(Name),
    case Debug of
        true -> io:fwrite("~s~n", [environment:get_output(run_string_debug(Contents))]);
        _ -> io:fwrite("~s~n", [environment:get_output(run_string(Contents))])
    end.

run_string(String) ->
    try runner:run(parser:parse(scanner:scan(String)))
	catch
		  {parser_error, Explanation} -> io:fwrite("~s~n", [Explanation])
	end.

run_string_debug(String) ->
    Scanned = scanner:scan(String),
    io:fwrite("Scanned: ~p~n", [Scanned]),
    Parsed = parser:parse(Scanned),
    io:fwrite("Parsed: ~p~n", [Parsed]),
    runner:run(Parsed).

%%%

test_set() -> [
    {"condition ya", fun(A) -> run_string(A) end,
        "HAI, WIN, O RLY?, YA RLY, 1, NO WAI, 2, OIC, KTHXBYE",
        environment:strip_scope(environment:assign_var(environment:new(), {identifier, "IT"}, {numbr,1}))},
    {"condition no", fun(A) -> run_string(A) end,
        "HAI, BOTH SAEM 1 AN 2, O RLY?, YA RLY, 1, NO WAI, 3, OIC, KTHXBYE",
        environment:strip_scope(environment:assign_var(environment:new(), {identifier, "IT"}, {numbr,3}))},
    {"condition mebbe", fun(A) -> run_string(A) end,
        "HAI, BOTH SAEM 1 AN 2, O RLY?, YA RLY, 1, MEBBE BOTH SAEM 1 AN 1, 2, NO WAI, 3, OIC, KTHXBYE",
        environment:strip_scope(environment:assign_var(environment:new(), {identifier, "IT"}, {numbr,2}))},
    {"switch", fun(A) -> run_string(A) end,
       "HAI, 1, WTF?, OMG 2, \"incorrect\", OMG 1, \"correct\", OIC, KTHXBYE",
       environment:strip_scope(environment:assign_var(environment:new(), {identifier, "IT"}, {yarn,"correct"}))},
    {"switch fall", fun(A) -> run_string(A) end,
       "HAI, 2, WTF?, OMG 2, \"incorrect\", OMG 1, \"correct\", OIC, KTHXBYE",
       environment:strip_scope(environment:assign_var(environment:new(), {identifier, "IT"}, {yarn,"correct"}))},
    {"switch gtfo", fun(A) -> run_string(A) end,
       "HAI, 2, WTF?, OMG 2, \"correct\", GTFO, OMG 1, \"incorrect\", OIC, KTHXBYE",
       environment:strip_scope(environment:assign_var(environment:new(), {identifier, "IT"}, {yarn,"correct"}))},
    {"switch catchall", fun(A) -> run_string(A) end,
       "HAI, 2, WTF?, OMG 1, \"incorrect\", GTFO, OMGWTF, \"correct\", OIC, KTHXBYE",
       environment:strip_scope(environment:assign_var(environment:new(), {identifier, "IT"}, {yarn,"correct"}))}
    ].

test() -> tester:test(test_set()).
